//
// Created by Zsir on 2025/7/25.
//

#include "threadPool.h"

threadPool::threadPool(int threadNum)
{
    pthread_mutex_init(&mutex_, nullptr);
    pthread_cond_init(&cond_, nullptr);
    shutdown_ = false;
    for (int i = 0; i < threadNum; ++i)
    {
        std::unique_ptr t = std::make_unique<Thread>(this);
        t->start();
        threads_.emplace_back(std::move(t));
    }
}

threadPool::~threadPool()
{
    shutDown();
    pthread_mutex_destroy(&mutex_);
    pthread_cond_destroy(&cond_);
}

void threadPool::shutDown()
{
    pthread_mutex_lock(&mutex_);
    shutdown_ = true;
    pthread_cond_broadcast(&cond_);
    pthread_mutex_unlock(&mutex_);
    for (auto &thread: threads_)
    {
        thread->stop();
    }
}

Task threadPool::getTask()
{
    pthread_mutex_lock(&mutex_);
    // 防止虚假唤醒，必须用while循环
    while (tasks_.empty() && !shutdown_)
    {
        pthread_cond_wait(&cond_, &mutex_);
    }
    Task task(nullptr, nullptr);
    if (!tasks_.empty())
    {
        task = *tasks_.front(); // FIFO，取队首任务
        tasks_.pop_front();    // FIFO，弹出队首任务
    }
    pthread_mutex_unlock(&mutex_);
    return task;
}

void threadPool::addTask(threadPool::Func func, void *data)
{
    pthread_mutex_lock(&mutex_);
    std::unique_ptr task = std::make_unique<Task>(func, data);
    tasks_.emplace_back(std::move(task));
    pthread_cond_signal(&cond_);
    pthread_mutex_unlock(&mutex_);
}

